from rest_framework.views import APIView
from rest_framework.response import Response
from .sers import *
from django.http.response import HttpResponse, FileResponse
from .utils import CodeUtils
from captcha.image import ImageCaptcha
from io import BytesIO
import redis

from .tasks import sendSMS

from rest_framework.throttling import AnonRateThrottle

r = redis.Redis(host="localhost", port="6379", decode_responses=True)
import time
from django.shortcuts import redirect


# 验证 用户名是否被使用
class UniqueUserView(APIView):
    def post(self, request):
        # 1、获取 传递来的用户名
        username = request.data.get("username")
        # 2、从数据库查询
        queryset = UserProfile.objects.filter(username=username)
        # 3、验证
        if queryset:
            return Response({"msg": "用户名已存在", "code": 400})
            # 4、返回
        return Response({"msg": "用户名可用", "code": 200})


# 定义一个注册接口

class RegisterView(APIView):

    def post(self, request):
        resp = {}

        # 获取 短信验证码
        sms_code = request.data.get("sms_code")
        phone = request.data.get("phone")

        sms_code_save = r.get(phone)

        if not sms_code_save:
            return Response({"msg": "手机验证码过期", "code": 400})
        if sms_code_save != sms_code:
            return Response({"msg": "手机验证码错误", "code": 400})

        # 获取传递来的 图片验证码

        img_code = request.data.get("img_code")

        # 获取传递来的 key
        key = request.GET.get("key")
        # redis取出 保存的
        code = r.get(key)
        print("img_code:", img_code)
        print("code:", code)
        if not code:
            return Response({"msg": "图片验证码过期", "code": 400})
        if code != img_code:
            return Response({"msg": "图片验证码错误", "code": 400})

        # 1、创建一个序列化类
        ser = UserSer(data=request.data)
        # 2、验证数据
        if ser.is_valid():
            # 3、保存
            ser.save()
            resp["msg"] = "注册成功"
            resp["code"] = 200
        else:
            resp["msg"] = "注册失败"
            resp["code"] = 400
            resp["errors"] = ser.errors
            # 4、返回
        return Response(resp)


# 验证码生成接口
def make_img_code(request):
    # 1、 先生成一个验证码
    code = CodeUtils.make_code_n(4)
    # 存储 验证码到 某个地方   陈明智 7788    王磊 9900
    # 获取 传递来的uuid
    key = request.GET.get("key")
    r.set(key, code, 60)
    # 2、生成一张图片对象
    image_captcha = ImageCaptcha()
    image = image_captcha.generate_image(code)
    # 创建一个 字节流
    bytes_io = BytesIO()
    # 要把对象存入字节流对象
    image.save(bytes_io, "jpeg")
    # 返回
    return HttpResponse(bytes_io.getvalue(), content_type="image/jpeg")


# 开发 调用短信的接口


class MySMSRateThrottle(AnonRateThrottle):
    rate = "1/minute"


class SMSCodeView(APIView):
    throttle_classes = [MySMSRateThrottle]

    def post(self, request):
        # 获取 传递来的手机号
        phone = request.data.get("phone")
        # 调用容联云SDK 实现 短信验证码发送
        # 验证码
        code = CodeUtils.make_code_n(4)
        # 保存到 我们的 redis中
        r.set(phone, code, 10 * 60)

        # 调用异步任务
        sendSMS.delay(phone, code)
        return Response({"msg": "验证码已经发送，请查收", "code": 200})


#  登录

from django.contrib.auth import authenticate

import jwt
from h2004a_md.settings import SECRET_KEY
import datetime
from django.db.models import Q
from django.contrib.auth.backends import ModelBackend


class MyModelBackend(ModelBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):
        user = UserProfile.objects.filter(Q(username=username) | Q(phone=username)).first()
        if user and user.check_password(password):
            return user
        else:
            return None


class LoginView(APIView):
    def post(self, request):



        # 验证数据
        # 查询到的 认证
        user = authenticate(**request.data)
        print(request.data)
        # 我要实现多账号查询

        # 判断
        if user:
            payload = {
                "uid": user.id,
                'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=2),
            }
            token = jwt.encode(payload, SECRET_KEY)
            return Response({"msg": "登录成功", "token": token, "code": 200})
        else:
            return Response({"msg": "登录失败", "code": 400})


# 开发一个 获取微博 认证页接口
from h2004a_md.settings import WEIBO_App_Key, WEIBO_URL, WEIBO_App_Secret
import requests
from urllib.parse import urlencode


class WeiboUrlView(APIView):
    def get(self, request):
        weibo_url = "https://api.weibo.com/oauth2/authorize?client_id={}&redirect_uri={}".format(WEIBO_App_Key,
                                                                                                      WEIBO_URL)
        # params = {
        #     "client_id": WEIBO_App_Key,
        #     "redirect_uri": WEIBO_URL,
        # }
        # weibo_url = weibo_url_base + urlencode(params)
        return Response({"url": weibo_url})

    def post(self, request):
        #  获取到code，然后 去 访问token
        code = request.data.get("code")

        r = requests.post("https://api.weibo.com/oauth2/access_token", {
            "client_id": WEIBO_App_Key,
            "client_secret": WEIBO_App_Secret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": WEIBO_URL
        })

        # 获取 返回的对象
        print(r.json())
        access_token = r.json()["access_token"]
        uid = r.json()["uid"]

        # 进行 三方用户的 注册操作，
        # 首先判断 用户有没有 之前 登录过，如果登录过呢 则 不注册，如果没有登录过 则注册
        openUser = OpenUser.objects.filter(uid="wb" + uid).first()
        if not openUser or not openUser.user:
            # 不存在，则注册
            openUser = OpenUser.objects.create(uid="wb" + uid, type="微博")
            return Response({"msg": "还没有绑定本地账号", "uid": openUser.uid, "code": 400})
        else:
            # 有这个月的三方账号，且已经绑定成功, 需要返回令牌
            # 判断
            user = openUser.user
            if user:
                payload = {
                    "uid": user.id,
                    'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=2),
                }
                token = jwt.encode(payload, SECRET_KEY)
                return Response({"msg": "登录成功", "token": token, "code": 200, "username": user.username})


def weibo_callback(request):
    code = request.GET.get("code")
    return redirect("http://127.0.0.1:8080/#/oauth?code=" + code)


# 三方账号 绑定 本地账号接口

class BindUserView(APIView):

    def post(self, request):
        # 绑定用户
        phone = request.data.get("phone")
        password = request.data.get("password")

        uid = request.data.get("uid")

        # 先去 数据库查询  是否存在该手机号
        user = UserProfile.objects.filter(phone=phone).first()

        # 查找到 三方账号
        open_user = OpenUser.objects.filter(uid=uid).first()
        if user:
            if not user.check_password(password):
                # 密码输入错误
                return Response({"msg": "密码输入错误，绑定失败"})
        else:
            # 该手机号 没有被使用过
            # 创建一个新的 本地账号
            user = UserProfile.objects.create_user(username="md" + phone, password=password, phone=phone)
        # 绑定 三方账号 到本地账号
        open_user.user = user
        open_user.save()
        return Response({"msg": "绑定成功"})
